﻿@page "/Account/Manage/GenerateRecoveryCodes"

@using Microsoft.AspNetCore.Identity
@using MyApp.Data

@inject UserManager<ApplicationUser> UserManager
@inject IdentityUserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager
@inject ILogger<GenerateRecoveryCodes> Logger

<PageTitle>Generate two-factor authentication (2FA) recovery codes</PageTitle>

<div class="max-w-xl">
    @if (recoveryCodes is not null)
    {
        <ShowRecoveryCodes RecoveryCodes="recoveryCodes.ToArray()" StatusMessage="@message" />
    }
    else
    {
        <Heading3>Generate two-factor authentication (2FA) recovery codes</Heading3>
        <Alert Type="AlertType.Warning">
            <p class="mb-3">
                <strong>Put these codes in a safe place.</strong>
            </p>
            <p class="mb-3">
                If you lose your device and don't have the recovery codes you will lose access to your account.
            </p>
            <p class="mb-3">
                Generating new recovery codes does not change the keys used in authenticator apps. 
                If you wish to change the key used in an authenticator app you should
                <HyperLink class="font-semibold" href="Account/Manage/ResetAuthenticator">reset your authenticator keys.</HyperLink>
            </p>
        </Alert>
        <div class="mt-4">
            <form @formname="generate-recovery-codes" @onsubmit="OnSubmitAsync" method="post">
                <AntiforgeryToken />
                <PrimaryButton Style="ButtonStyle.Red" type="submit">Generate Recovery Codes</PrimaryButton>
            </form>
        </div>
    }
</div>

@code {
    private string? message;
    private ApplicationUser user = default!;
    private IEnumerable<string>? recoveryCodes;

    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        user = await UserAccessor.GetRequiredUserAsync(HttpContext);

        var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user);
        if (!isTwoFactorEnabled)
        {
            throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled.");
        }
    }

    private async Task OnSubmitAsync()
    {
        var userId = await UserManager.GetUserIdAsync(user);
        recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
        message = "You have generated new recovery codes.";

        Logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", userId);
    }
}
